home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
mus
/
play
/
multiplsr.lha
/
window.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-14
|
12KB
|
589 lines
/*
* MultiPlayer
* Copyright (C) 1992 Bryan Ford
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* I (the author of MultiPlayer) can be contacted on the Internet at
* "bryan.ford@m.cc.utah.edu". See "Player.doc" for other addresses.
*
* $Id: window.c,v 4.4 92/07/19 18:09:48 BAF Exp $
*
* $Log: window.c,v $
* Revision 4.4 92/07/19 18:09:48 BAF
* Adjustment for putting localdata back into RemindNodes
*
* Revision 4.3 92/07/12 08:26:40 BAF
* end() waits with an EasyRequester as necessary until font requester comes down
* Enforcer bug with DrawInfo fixed
*
* Revision 4.2 92/06/21 11:13:00 BAF
* Migrated regargs to stdargs
*
* Revision 4.1 92/06/06 19:56:05 BAF
* Major_code_cleanup
*
* Revision 3.1 92/05/25 07:53:28 BAF
* GNU-ized.
*
*
*/
#include <exec/types.h>
#include <exec/execbase.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/wb.h>
#include "bry/macros.h"
#include "bry/clist.h"
#include "bry/remind.h"
#include "bry/misc.h"
#include "bry/guido.h"
#include "player.h"
#define THEIGHT (10)
#define ZHEIGHT (10+4+16*6+18*2+2)
#define ERRORLIFE 4 // How long an error stays in the title bar
struct Screen *playerscreen;
extern struct ExecBase *SysBase;
extern char *modname, *modtypename, *authorname, **songcatalog;
extern GuidoSpec windowspec, windowfrspec;
struct Gadget *windowmodgad, *windowtypegad, *windowauthorgad, *windowsonggad,
*windowvolumegad, *windowbalancegad, *windowbalanceresetgad,
*windowspeedgad, *windowjumpbackgad, *windowjumpforwardgad;
extern long songpos, songlen; // Displayed in the window titlebar
static struct DrawInfo *dri;
static struct Screen *driscreen;
static struct AppWindow *awin;
static char * errmsg;
static short errlife;
static char frclear;
static void *ifr;
static long timer(void);
static long end(void);
static long check(long sigmask);
static long update(void);
static long close(int remake);
static void snapshotwin(void);
static void doremake(void);
static void initfunc(void);
void windowsettingsupdate(void);
static struct RemindNode timernode = {{0},timer};
static struct RemindNode updatenode = {{0},update};
static struct RemindNode endnode = {{0},end};
static struct RemindNode remakenode = {{0},doremake};
static struct MPWin mpwin = {windowspec,0L,initfunc,
{{0},snapshotwin,(long)&mpwin},
{{0},check,(long)&mpwin},
{{0},close,(long)&mpwin}};
void
windowupdatetimer(void)
{
extern struct TextAttr topaz8;
extern char *modname;
static struct IntuiText itext = {1,0,JAM2,0,1,&topaz8};
char buf[32];
struct Window *win;
if(!(win = mpwin.win))
return;
sysflags &= ~SF_TIMERUP;
if((showmode == SM_NOTHING) || (!modname) || (!win))
return;
if((songlen >= 0) && (showmode != SM_CLOCK))
{
sprintf(buf," %ld/%ld",songpos + (showmode - SM_SEQUENCE0),songlen);
}
else
{
extern long songtime;
long time = songtime/60;
sprintf(buf," %ld:%02ld",time/60,time%60);
}
itext.IText = buf;
if(dri)
{
if(win->Flags & WFLG_WINDOWACTIVE)
{
itext.FrontPen = dri->dri_Pens[FILLTEXTPEN];
itext.BackPen = dri->dri_Pens[FILLPEN];
}
else
{
itext.FrontPen = dri->dri_Pens[TEXTPEN];
itext.BackPen = dri->dri_Pens[BACKGROUNDPEN];
}
}
PrintIText(win->RPort,&itext,win->Width-50-strlen(buf)*8,0);
}
static void updatetitle(void)
{
extern char copyright[];
if(!mpwin.win)
return;
SetWindowTitles(mpwin.win,errlife ? errmsg :
modname ? modname : "MultiPlayer",copyright);
windowupdatetimer();
}
static long
timer(void)
{
if((errlife) && (--errlife == 0))
updatetitle();
else if((songlen < 0) || (showmode == SM_CLOCK))
windowupdatetimer();
return(0);
}
static long
update(void)
{
static char nosongstext[] = "";
static char *nosongslab[2] = {nosongstext,0};
extern long cursong;
struct Window *win;
if(win = mpwin.win)
{
updatetitle();
GSetText(win,windowmodgad,modname);
GSetText(win,windowtypegad,modtypename);
GSetText(win,windowauthorgad,authorname);
GSetCycleOptions(win,windowsonggad,songcatalog ? songcatalog : nosongslab,cursong);
GEnDisGadgets(win,modtype & MTF_JUMP,
windowjumpbackgad,
windowjumpforwardgad,
0L);
}
return(0);
}
static void
snapshotwin(void)
{
extern short zoomwinleft, zoomwintop;
extern short tinywinleft, tinywintop;
struct Window *win = mpwin.win;
if(win->Flags & WFLG_ZOOMED)
{
zoomwinleft = win->LeftEdge;
zoomwintop = win->TopEdge;
}
else
{
tinywinleft = win->LeftEdge;
tinywintop = win->TopEdge;
}
}
static long
close(int remake)
{
char *windowopen(void);
remind_rem(&timernode);
remind_rem(&updatenode);
remind_rem(&endnode);
if(dri)
{
FreeScreenDrawInfo(driscreen,dri);
dri = 0L;
}
if(awin)
{
RemoveAppWindow(awin);
awin = 0L;
}
closempwin(&mpwin);
if(remake)
showerr(openmpwin(&mpwin));
else
adddo(&endnode);
return(0);
}
static long end(void)
{
struct Screen *pubscreen;
pubscreen = playerscreen, playerscreen = 0;
remind_callrem(&closelist,0);
if(pubscreen)
UnlockPubScreen(0L,pubscreen);
remind_rem(&remakenode);
return(0);
}
static void
doremake(void)
{
struct RemindList templist;
struct RemindNode *node;
remind_initlist(&templist);
while(node = clist_remhead(&closelist))
clist_addtail(&templist,node);
remind_callrem(&templist,1);
}
void
windowremake(void)
{
remind_add(&dolist,&remakenode);
}
static long
frcheck(void)
{
struct WBArg *args;
long count;
if(ifr && ((count = GCheckRequester(ifr,&args)) >= 0))
{
extern short modfrleft;
GGetRequesterLocation(ifr,&modfrleft);
if(count)
{
if(frclear)
progclear();
if(!showerr(progaddargs(count,args)))
if(frclear)
showerr(progstart());
}
}
return(0);
}
static struct RemindNode frchecknode = {{0},frcheck};
static long
frend(void)
{
if(ifr)
{
while(GDeleteRequester(ifr))
{
static struct EasyStruct easy = {
sizeof(easy),0,"MultiPlayer","Please close all file and font requesters","OK"};
EasyRequestArgs(0,&easy,0,0);
}
ifr = 0L;
}
remind_rem(&frchecknode);
return(0);
}
static struct RemindNode frendnode = {{0},frend,-100};
static void
addfrcalls(void)
{
addcalls(&frchecknode,0,0,&frendnode);
}
char *
reqmod(int clear)
{
struct {
struct Window *win;
char *oktext;
} params;
int rc;
if(!mpwin.win)
return("Window not open");
params.win = mpwin.win;
params.oktext = (frclear = clear) ? "Play" : "Add";
if(!ifr && !(ifr = GCreateRequester(windowfrspec)))
showerr("File requester unavailable");
else
{
addfrcalls();
if((rc = GOpenRequester(ifr,windowfrspec,¶ms)) == 0)
return("File requester in use");
else if(rc < 0)
return("Not enough memory");
}
return(0);
}
void
windowsettingsupdate(void)
{
extern short mspeed, mvolume, mbalance;
int endis;
struct Window * win = mpwin.win;
if(!win)
return;
endis = 0;
if((!curmod) || (curmod->volume >= 0))
{
GSetSliderLevel(win,windowvolumegad,mvolume);
GSetSliderLevel(win,windowbalancegad,mbalance);
endis = 1;
}
GEnDisGadgets(win,endis,
windowvolumegad,
windowbalancegad,
windowbalanceresetgad,
0L);
endis = 0;
if((!curmod) || (curmod->speed))
GSetSliderLevel(win,windowspeedgad,mspeed),
endis = 1;
GEnDisGadget(win,endis,windowspeedgad);
}
void
gui_windowsong(struct GuidoMessage *im)
{
setsong(im->Code);
}
void
gui_windowvolume(struct GuidoMessage *gm)
{
extern void playervolume(void);
extern short mvolume;
mvolume = gm->Code;
playervolume();
}
void
gui_windowbalance(struct GuidoMessage *gm)
{
extern void playervolume(void);
extern short mbalance;
mbalance = gm->Code;
playervolume();
}
void
gui_windowbalancereset(void)
{
extern void playervolume(void);
extern short mbalance;
mbalance = 0;
GSetSliderLevel(mpwin.win,windowbalancegad,0);
playervolume();
}
void
gui_windowspeed(struct GuidoMessage *gm)
{
extern void playerspeed(void);
mspeed = gm->Code;
playerspeed();
}
void
gui_windoweject(void)
{
endmod();
GlobSetLong(&curmod,0L,0);
}
void
gui_windownext(void)
{
showerr(prognext());
}
void
gui_windowprev(void)
{
showerr(progprev());
}
void
gui_windownew(void)
{
showerr(reqmod(1));
}
void
windowerror(char *mes)
{
if(mpwin.win)
{
errmsg = mes;
errlife = ERRORLIFE;
updatetitle();
}
}
/* Zoom/unzoom the main window */
static void
windowzoom(void)
{
if(mpwin.win)
ZipWindow(mpwin.win);
}
void
gui_windowzoom(void)
{
windowzoom();
}
/* Handle button-down events from all MultiPlayer windows */
void
windowclick(int code)
{
if(code == MENUDOWN)
showerr(progwinopenclose());
if(code == MIDDLEDOWN)
windowzoom();
}
/* Guido default callback function, called from within check() */
static void
callback(struct GuidoMessage *im)
{
switch(im->Class)
{
case IDCMP_ACTIVEWINDOW:
case IDCMP_INACTIVEWINDOW:
case IDCMP_REFRESHWINDOW:
windowupdatetimer();
break;
case IDCMP_CHANGEWINDOW:
snapshotwin();
break;
}
standardcallback(im);
}
/* Window-check called from CheckList */
static long
check(long sigmask)
{
if((sigmask & mpwin.sigmask) && GCheckPanel(mpwin.win,callback,0L))
{
extern struct Library *CxBase;
extern char hotkey[];
if((hotkey[0]) && (CxBase))
windowclose();
else
sysflags |= SF_KILL;
}
return(0);
}
/* Called from openmpwin() for initialization */
static void
initfunc(void)
{
remind_rem(&remakenode);
if(mpwin.win)
{
dri = GetScreenDrawInfo(driscreen = mpwin.win->WScreen);
remind_add(&timerlist,&timernode);
remind_add(&updatelist,&updatenode);
remind_add(&endlist,&endnode);
if(wbappport)
awin = AddAppWindowA(1,0,mpwin.win,wbappport,0);
update();
windowsettingsupdate();
}
}
/* Close the main window and all other Workbench-style windows */
void
windowclose(void)
{
setfinmpwin(&mpwin);
}
/* Open the main MultiPlayer window (and any flashy window currently enabled),
or simply activates it if it's already open. */
char *
windowopen(void)
{
extern short tinywinleft;
extern char flashflags;
extern char *flashywinopenclose(void);
char *err = 0;
if(mpwin.win)
{
WindowToFront(mpwin.win);
ActivateWindow(mpwin.win);
return(0L);
}
/* User interface only works with 2.04+ */
if(SysBase->LibNode.lib_Version < 37)
return("Kickstart 2.04 or later required");
if(!playerscreen
&& !(playerscreen = LockPubScreen(argarray.screen)))
return("Public screen unavailable");
if(tinywinleft < 0)
tinywinleft = playerscreen->Width-23-320;
/* First open the flashy windows */
if(flashflags)
err = flashywinopenclose();
/* Then open the main control panel (on top) */
return(err ? err : openmpwin(&mpwin));
}